/**
 *	@file	safari_o.c
 *	@brief	サファリOBJOBJレイアウトツール
 *	@author	Miyuki Iwasawa
 *	@date	08.10.10
 */

#include "common.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/brightness.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/window.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/wipe.h"
#include "system/wordset.h"
#include "system/buflen.h"
#include "system/pm_rtc.h"
#include "gflib/msg_print.h"
#include "gflib/strbuf_family.h"
#include "application/app_tool.h"
#include "savedata/config.h"
#include "savedata/gametime.h"
#include "field/script_def.h"	//SAFARI_OBJ_ID_NULL

#include "application/safari_l.h"
#include "safario_sys.h"
#include "safario_sub.h"
#include "safario_objlist.h"

#include "msgdata/msg.naix"


//================================================================
//----------------------------------------------------------------
///定義
//----------------------------------------------------------------
//================================================================



//================================================================
//----------------------------------------------------------------
///プロトタイプ
//----------------------------------------------------------------
//================================================================
static void sub_InitDataSet(SAFARIO_WORK* wk,SAFARI_LTPARAM* sp);
static void sub_LastDataSet(SAFARIO_WORK* wk);
static void sub_ViewClear(void);

static int seq_ObjSelect(SAFARIO_WORK* wk);
static int seq_ObjPlace(SAFARIO_WORK* wk);
static int seq_FadeIn(SAFARIO_WORK* wk);
static int seq_FadeOut(SAFARIO_WORK* wk);

static void sub_AddObj(SAFARIO_WORK* wk);

//================================================================
//----------------------------------------------------------------
///プログラムエリア
//----------------------------------------------------------------
//================================================================

//----------------------------------------------------------------
///グローバルエリア
//----------------------------------------------------------------
/**
 *	@brief	OBJレイアウトツール プロセス初期化
 *	@param	proc	プロセスデータ
 *	@param	seq		シーケンス
 *
 *	@return	処理状況
 */
PROC_RESULT SafariObjProc_Init( PROC *proc,int *seq)
{
	switch(*seq){
	case 0:
		sub_ViewClear();

		//ワークエリア取得
		HeapStatePush();
		//ヒープ作成
		sys_CreateHeap(HEAPID_BASE_APP,HEAPID_SAFARI_APP,0x48000);

		{
			SAFARIO_WORK *wk = NULL;
			SAFARI_LTPARAM * sp;

			sp = (SAFARI_LTPARAM*)PROC_GetParentWork(proc);

			wk = PROC_AllocWork( proc,sizeof(SAFARIO_WORK),HEAPID_SAFARI_APP);
			MI_CpuClear8(wk,sizeof(SAFARIO_WORK));

			//パラメータ引継ぎ
			wk->heapID = HEAPID_SAFARI_APP;

			sub_InitDataSet(wk,sp);
		}
		Snd_DataSetByScene( SND_SCENE_SUB_SAFARI, 0, 0 ); //サウンドデータロード(BGM引継ぎ)
		(*seq)++;
		break;
	case 1:
		if(!SafariObjSeq_AppInit((SAFARIO_WORK*)PROC_GetWork(proc))){
			break;
		}
		return PROC_RES_FINISH;
	}
	return PROC_RES_CONTINUE;
}

/**
 *	@brief	OBJレイアウトツール　プロセス終了
 *	@param	proc	プロセスデータ
 *	@param	seq		シーケンス
 *
 *	@return	処理状況
 */
PROC_RESULT SafariObjProc_End( PROC *proc,int *seq)
{
	int heapID;
	SAFARIO_WORK* wk = PROC_GetWork(proc);

	if(!SafariObjSeq_AppEnd(wk)){
		return PROC_RES_CONTINUE;
	}
	sub_ViewClear();

	//データセット
	sub_LastDataSet(wk);
	heapID = wk->heapID;

	//ワークエリア解放
	MI_CpuClear8(wk,sizeof(SAFARIO_WORK));
	PROC_FreeWork(proc);

	HeapStatePop();
	HeapStateCheck(heapID);
	sys_DeleteHeap(heapID);

	return PROC_RES_FINISH;
}


/***
 *	@brief	OBJレイアウトツール　メインプロセス
 */
PROC_RESULT	SafariObjProc_Main( PROC *proc,int* seq)
{
	int end_f = 0;
	SAFARIO_WORK* wk = PROC_GetWork(proc);

	switch(*seq){
	case SEQ_FADEIN:
		*seq = seq_FadeIn(wk);
		break;
	case SEQ_OBJ_SELECT:
		*seq = seq_ObjSelect(wk);
		break;
	case SEQ_OBJ_PLACE:
		*seq = seq_ObjPlace(wk);
		break;
	case SEQ_FADEOUT:
		*seq = seq_FadeOut(wk);
		break;
	case SEQ_EXIT:
		return PROC_RES_FINISH;
	default:
		break;
	}
	CATS_Draw(wk->pActRes);
	SafariObj_3DMain(&wk->sys3d);
	return PROC_RES_CONTINUE;
}


/////////////////////////////////////////////////////////////////////////
//ローカル

/*
 *	@brief	アプリ初期化データセット
 */
static void sub_InitDataSet(SAFARIO_WORK* wk,SAFARI_LTPARAM* sp)
{
	CONFIG* config_sv;

	wk->safari_sv = SaveData_GetSafariSave(sp->save);
	SafariSv_GetLayout(wk->safari_sv,SAFARI_LAYOUT_MINE,&wk->layout);

	config_sv = SaveData_GetConfig(sp->save);
	wk->msg_spd	= CONFIG_GetMsgSpeed(config_sv);
	wk->win_type = CONFIG_GetWindowType(config_sv);

	//現在のキー動作モードを取得
	wk->key_mode = KeyTouchStatus_CheckTouchOrKey((KEYTOUCH_STATUS*)sp->kt_status);

	wk->param = sp;

	//初期カーソル位置取得
	wk->pos = *(wk->param->cursor_p) % PAGE_ITEM_MAX;
	wk->page = *(wk->param->cursor_p) / PAGE_ITEM_MAX;

	//表示オブジェクトリストを取得
	{
		MYSTATUS* my = SaveData_GetMyStatus(sp->save);
		u8 obj_level = SafariSv_GetObjLevel(wk->safari_sv);
		u32 my_id = MyStatus_GetID(my);
		u8	my_sex = MyStatus_GetMySex(my);
		#ifdef PM_DEBUG
			if(sys.cont & PAD_BUTTON_L){
				obj_level = SAFARI_OBJ_LEVEL_MAX;
			}
		#endif
		wk->obj = SafariObjData_AllocObjList(my_id,obj_level,my_sex,&wk->list_max,wk->heapID);
	}
	//自分がいるブロックIDを取得
	wk->now_block = sp->block_id;
	if(wk->now_block > 5){
		wk->now_block = 0;
	}
	//追加でおけるOBJ数
	wk->rest_obj = SAFARI_OBJ_MAX-wk->layout.block[wk->now_block].obj_ct;

	//ページの最大数算出
	wk->page_max = wk->list_max/PAGE_ITEM_MAX;
	if((wk->list_max % PAGE_ITEM_MAX) > 0){
		wk->page_max += 1;
	}
	if(wk->page >= wk->page_max){
		wk->page = 0;
	}
	//戻り値クリア
	wk->param->ret_value = SAFARI_OBJ_ID_NULL;

	//現在のタイムゾーン取得
	{
		GMTIME * tm = SaveData_GetGameTime(sp->save);
		wk->anm_time_zone = GF_RTC_ConvertHourToTimeZone(tm->sv_time.hour);

		if(wk->anm_time_zone == TIMEZONE_MIDNIGHT){
			wk->anm_time_zone = TIMEZONE_NIGHT;	//深夜は夜と同じアニメ
		}
	}
}

/*
 *	@brief	アプリセーブデータ反映
 */
static void sub_LastDataSet(SAFARIO_WORK* wk)
{
	//オブジェリストデータ破棄
	sys_FreeMemoryEz(wk->obj);

	//OBJレイアウトデータ書き戻し
	SafariSv_SetLayout(wk->safari_sv,SAFARI_LAYOUT_MINE,(const SAFARI_LAYOUT*)&wk->layout);

	//初期カーソル位置保存
	if(wk->pos >= PAGE_ITEM_MAX){
		wk->pos = PAGE_ITEM_MAX-1;	//「もどる」にカーソルがある場合、一つ前で覚える
	}
	*(wk->param->cursor_p) = (wk->page*PAGE_ITEM_MAX)+wk->pos;

	//現在のキー動作モードを書き戻し
	KeyTouchStatus_SetTouchOrKey((KEYTOUCH_STATUS*)wk->param->kt_status,wk->key_mode);
}

/*
 *	@brief	ビュー初期化
 */
static void sub_ViewClear(void)
{
	//Blank関数リセット
	sys_VBlankFuncChange(NULL, NULL);
	sys_HBlankIntrStop();	//HBlank割り込み停止

	GF_Disp_GX_VisibleControlInit();
	GF_Disp_GXS_VisibleControlInit();
	GX_SetVisiblePlane(0);
	GXS_SetVisiblePlane(0);
	WIPE_SetBrightness(WIPE_DISP_MAIN,WIPE_FADE_BLACK);
	WIPE_SetBrightness(WIPE_DISP_SUB,WIPE_FADE_BLACK);
	WIPE_ResetWndMask(WIPE_DISP_MAIN);
	WIPE_ResetWndMask(WIPE_DISP_SUB);
}

/*
 *	@brief	ブロック選択メイン
 */
static int seq_ObjSelect(SAFARIO_WORK* wk)
{
	int ret;

	switch(wk->seq){
	case LSEQ_NULL:
		wk->seq = SafariObj_Input(wk);
		break;
	case LSEQ_PLACE_CHK:
		wk->seq = 0;
		return SEQ_OBJ_PLACE;
	case LSEQ_MSG_WAIT:
		wk->seq = SafariObj_MsgWait(wk);
		break;
	case LSEQ_END:
		wk->seq = 0;
		return wk->next_seq;
	}
	return SEQ_OBJ_SELECT;
}

/*
 *	@brief	オブジェ配置選択メイン
 */
static int seq_ObjPlace(SAFARIO_WORK* wk)
{
	int ret;

	switch(wk->seq){
	case 0:
		SafariObj_ViewChange(wk,VIEW_TARGET);
		SafariObj_YesNoBtnSet(wk);
		wk->seq++;
		break;
	case 1:
		ret = SafariObj_YesNoBtnWait(wk);
		if(ret < 0){
			break;
		}
		if(ret == 1){
			sub_AddObj(wk);
			wk->seq = 0;
			return SEQ_FADEOUT;
		}
		wk->seq++;
		break;
	default:
		SafariObj_ViewChange(wk,VIEW_SELECT);
		wk->seq = 0;
		return SEQ_OBJ_SELECT;
	}
	return SEQ_OBJ_PLACE;
}

/**
 *	@brief	フェードイン
 */
static int seq_FadeIn(SAFARIO_WORK* wk)
{
	switch(wk->seq){
	case 0:
		WIPE_SYS_Start(WIPE_PATTERN_WMS,
				WIPE_TYPE_FADEIN,
				WIPE_TYPE_FADEIN,0x0000,COMM_BRIGHTNESS_SYNC,1,wk->heapID
				);
		GF_Disp_GX_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_ON );
		GF_Disp_GXS_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_ON );
		++wk->seq;
		break;
	case 1:
		if(!WIPE_SYS_EndCheck()){
			break;
		}
		wk->seq = 0;
		return SEQ_OBJ_SELECT;
	}
	return SEQ_FADEIN;
}

/**
 *	@brief	フェードアウト
 */
static int seq_FadeOut(SAFARIO_WORK* wk)
{

	switch(wk->seq){
	case 0:
		WIPE_SYS_Start(WIPE_PATTERN_WMS,
				WIPE_TYPE_FADEOUT,
				WIPE_TYPE_FADEOUT,0x0000,COMM_BRIGHTNESS_SYNC,1,wk->heapID
				);
		++wk->seq;
		break;
	case 1:
		if(!WIPE_SYS_EndCheck()){
			break;
		}
		wk->seq = 0;
		return SEQ_EXIT;
	}
	return SEQ_FADEOUT;
}

/**
 *	@brief	セーブデータにオブジェクト追加
 */
static void sub_AddObj(SAFARIO_WORK* wk)
{
	u8	x,z,bx,bz;
	SAFARI_OBJ obj;
	SAFARI_OBJ_LIST* pl;

	//オフセット座標算出
	bx = wk->param->block_id % SAFARI_FIELD_X;
	bz = wk->param->block_id / SAFARI_FIELD_X;

	MI_CpuClear8(&obj,sizeof(SAFARI_OBJ));
	pl = &wk->obj[wk->target];

	obj.id = pl->id;
	obj.x = wk->param->obj_spc[pl->siz].x % 32;
	obj.z = wk->param->obj_spc[pl->siz].z % 32;
	obj.y = wk->param->height;

	IWASAWA_PRINT("サファリオブジェ追加! id = %d  block%d (%d,%d,%d)\n",
		obj.id,wk->param->block_id,obj.x,obj.y,obj.z);

	//データ追加
	SafariLayout_AddObj(&wk->layout,wk->param->block_id,&obj);

	//戻り値セット
	wk->param->ret_value = obj.id;
}
